package com.gitee.feizns.quickstart.log.spring.boot.autoconfigure.db.mybatis.flex.pojo;

import com.fasterxml.jackson.databind.JsonNode;
import com.gitee.feizns.quickstart.ddl.annotation.Comment;
import com.gitee.feizns.quickstart.jackson.JsonUtils;
import com.gitee.feizns.quickstart.log.MethodLog;
import com.gitee.feizns.quickstart.log.QkLogErrorType;
import com.gitee.feizns.quickstart.log.spring.boot.autoconfigure.db.DbLog;
import com.gitee.feizns.quickstart.log.spring.boot.autoconfigure.db.Web;
import com.gitee.feizns.quickstart.web.WebUtils;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.core.handler.JacksonTypeHandler;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.Type;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * qk日志
 * @author feizns
 * @since 2024/12/20
 */
@Entity
@Getter
@Setter
@Comment("qk日志")
@ToString(callSuper = true)
public class QkLog implements DbLog<QkLog> {

    /**
     * （主键）编号
     */
    @Id
    @Comment("自增主键编号")
    @com.mybatisflex.annotation.Id(keyType = KeyType.Auto)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(nullable = false, columnDefinition = "BIGINT UNSIGNED")
    protected Long id;

    /**
     * 日志类型
     */
    @Comment("日志类型")
    private String type;

    /**
     * 日志描述
     */
    @Comment("日志描述")
    @Column(columnDefinition = "TEXT")
    private String description;

    /**
     * 请求参数
     */
    @Type(type = "json")
    @Comment("请求参数")
    @Column(columnDefinition = "JSON")
    @com.mybatisflex.annotation.Column(typeHandler = JacksonTypeHandler .class)
    private JsonNode args;

    /**
     * 返回结果值
     */
    @Type(type = "json")
    @Comment("返回结果值")
    @Column(columnDefinition = "JSON")
    @com.mybatisflex.annotation.Column(typeHandler = JacksonTypeHandler .class)
    private JsonNode result;

    /**
     * 操作时间
     */
    @Comment("操作时间")
    private LocalDateTime time;

    /**
     * 异常信息
     */
    @Comment("异常信息")
    @Column(columnDefinition = "TEXT")
    private String exception;

    /**
     * 请求头列表
     */
    @Type(type = "json")
    @Comment("请求头列表")
    @Column(columnDefinition = "JSON")
    @com.mybatisflex.annotation.Column(typeHandler = JacksonTypeHandler.class)
    private JsonNode headers;

    /**
     * 请求IP
     */
    @Comment("请求IP")
    private String ip;

    /**
     * 请求方法
     */
    @Comment("请求方法")
    @Column(columnDefinition = "VARCHAR(10)")
    private String method;

    /**
     * 请求路径
     */
    @Comment("请求路径")
    private String url;

    /**
     * 用户编号
     */
    @Comment("用户编号")
    private String userId;

    @Override
    public QkLog apply(MethodLog log, QkLogErrorType errorType) {
        this.setType(log.getType());
        this.setDescription(log.getDescription());
        this.setArgs(JsonUtils.node(log.getArgs()));
        if ( log.getResult() != null )
            this.setResult(JsonUtils.node(log.getResult()));
        this.setTime(LocalDateTime.now());
        this.setHeaders(JsonUtils.node(Web.headers()));
        this.setIp(WebUtils.getIpAddress());
        this.setUrl(Web.requestUrl());
        this.setMethod(Web.requestMethod());
        Object userid = log.getUserid();
        if ( userid != null )
            this.setUserId(Objects.toString(log.getUserid()));
        //异常信息
        if ( log.hasException() ) {
            if ( errorType == QkLogErrorType.Message )
                this.setException(log.exceptionMessage());
            else if ( errorType == QkLogErrorType.PrintStackTrace )
                this.setException(log.printStackTraceMessage());
        }
        return this;
    }

}
